package com.zkingsoft.quartz;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.matrix.core.tools.LogUtil;
import com.matrix.core.tools.PropertiesUtil;


/**
 * 定时清理LOG文件
 * @author zhangheng
 *
 */
public class ClearLogFileJob extends QuartzJobBean{
	//matrix日志文件路径
	private static final String LOG_PATH = "log_path";
	//日志文件清理阀值
	private static final String LOG_MAX = "log_max";
	//清理前N天数
	private static final String LOG_CLEAR_DAY = "log_clear_day";

    

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		 File directory = new File("");// 参数为空 /home/javaweb/tomcat8080
	      String courseFile = null;
		try {
			//项目服务器脚本文件路径
			courseFile = directory.getCanonicalPath();
		} catch (IOException e1) {
			LogUtil.error("================获取项目tomcat路径失败================",e1);
		}
	//日志文件名格式 ：debug.log.2018-04-18   error.log.2018-04-18 info.log.2018-04-18
	//String filePath = "C:\\"+"\\matrix4\\"+"debug.log.2018-04-18";
	//从config/core/system.properties文件读取数据
	String 	log_path = PropertiesUtil.getString(LOG_PATH);
	String  log_max = PropertiesUtil.getString(LOG_MAX);
	String  log_clear_day = PropertiesUtil.getString(LOG_CLEAR_DAY);
	//tomcat直接获取
	//String tomcat_log_path = PropertiesUtil.getString(TOMCAT_LOG_PATH);
	String tomcat_log_path = courseFile+"/logs";
	
	if(!StringUtils.isBlank(log_path) &&!StringUtils.isBlank(log_max)&&
			!StringUtils.isBlank(log_clear_day)&&!StringUtils.isBlank(tomcat_log_path)) {
		Long maxMb = Long.valueOf(log_max);
		Integer claerDay = Integer.valueOf(log_clear_day);
		//每X小时检查一次日志路径和tomcat中日志大小，超过xMB则删除最近x天前的日志
		LogUtil.info("================定时清理LOG:{}================",log_path);
		//TODO 不要matrix4
		String basePath =  log_path;
		File logFileDir = new File(basePath);
		File tomcatLogFile = new File(tomcat_log_path);
		Long logLength = getLengthByDirFile(logFileDir,tomcatLogFile);
		//获取日志文件总大小 单位：MB
		Long logLengMB = logLength/(1024*1024);	
		LogUtil.info("================LOG文件大小:{}MB================",logLengMB);
		LogUtil.info("================清理阀值:{}MB================",maxMb);
		if(logLengMB>=maxMb) {
			//覆盖tomcat下的catalina.out
			String catalinaPath = tomcat_log_path+"/catalina.out";
			LogUtil.info("================tomcat日志目录:{}================",catalinaPath);
			File cataFile = new File(catalinaPath);
			if(cataFile.exists()) {
				FileWriter fw = null;
				try {
					fw = new FileWriter(cataFile);
					SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");   
					Date clearDate = new Date();
					String clearDateString  =sdf.format(clearDate);
					String writerContent = "==========="+clearDateString+"清理catalina.out日志文件===========";
					fw.write(writerContent);
					LogUtil.info("================清理tomcat-catalina.out日志完毕================");
				} catch (IOException e) {
					LogUtil.error("清理catalina.out文件失败,文件路径：{}", catalinaPath,e);
				}finally {
					if(fw!=null) {
						try {
							//关闭输出
							fw.close();
						} catch (IOException e) {
							LogUtil.error("关闭输出失败,文件路径：{}", catalinaPath,e);
						}
					}
				}
			
			}
			//这个只针对matrix日志
			List<String> delList =getBeforeWhenDatestring(logFileDir, claerDay);  
			if(CollectionUtils.isNotEmpty(delList)) {
				LogUtil.info("================开始清理:{}================",delList);
				//删除matrix4下的log
				deleteFiles(logFileDir, delList, basePath);
			}
		}
	}else {
		LogUtil.info("================未配置日志文件路径等参数,无法自动清理日志文件================");
	}
		
	}
	
	
	/**
	 * 返回日志文件夹长度 单位：byte
	 * @author ZHANGHENG
	 * @email 512061637@qq.com
	 * @date 2018年5月7日
	 * @param file
	 * @return
	 */
	public static Long getLengthByDirFile(File logFileDir,File tomcatLogFile) {
			Long logLengthMatrix = 0l;
			Long logLengthTomcat = 0l;
			//matrix4日志
			if(logFileDir.exists()) {
				if(logFileDir.isDirectory()) {
					File[] logFileArr = logFileDir.listFiles();
					if(null != logFileArr && logFileArr.length>0) {
						for(File fileTemp:logFileArr) {
							logLengthMatrix+=fileTemp.length();
						}
					}
				}
			}
			//tomcat日志
			if(tomcatLogFile.exists()) {
				if(tomcatLogFile.isDirectory()) {
					File[] tomcatLogFileArr = tomcatLogFile.listFiles();
					if(null != tomcatLogFileArr && tomcatLogFileArr.length>0) {
						for(File fileTemp:tomcatLogFileArr) {
							logLengthTomcat+=fileTemp.length();
						}
					}
				}
			}
			return logLengthMatrix+logLengthTomcat;
	}
	
	/**
	 * 获取需要删除的文件名（日期）2018-05-05
	 * @author ZHANGHENG
	 * @email 512061637@qq.com
	 * @date 2018年5月7日
	 * @param logFileDir
	 * @param dayNum
	 * @return
	 */
	public static List<String> getBeforeWhenDatestring(File logFileDir,int dayNum){
		        //若超过xM就删除x天前的文件
				//int dayNum = dayNum;
				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
		        Date date=new Date();  
		        Calendar calendar = Calendar.getInstance();  
		        calendar.setTime(date);  
		        calendar.add(Calendar.DAY_OF_MONTH, -dayNum);  
		        //获得了前x天的日期
		        date = calendar.getTime();  
		        //获取需要删除的文件名
		        List<String> deleteList = new ArrayList<String>();
		        for(String fileName :logFileDir.list()) {
		        	if(fileName.contains("log.")) {
		        		//文件日期
		        		String fileDate = fileName.substring(fileName.indexOf("log.")+4);
		        		//找出x天前的文件日期
		        		Date dateTemp;
						try {
							dateTemp = sdf.parse(fileDate);
			        		if(dateTemp.before(date)) {
			        			//将指定日期之前的日期加入到待删除文件名日期集合中
			        			if(!deleteList.contains(fileDate)) {
			        				deleteList.add(fileDate);
			        			}
			        		}
						} catch (ParseException e) {
							LogUtil.error(fileName, "转换日期异常");
						}
		        		
		        	}
		        }
		        return deleteList;
	}
	
	/**
	 * 删除文件
	 * @author ZHANGHENG
	 * @email 512061637@qq.com
	 * @date 2018年5月7日
	 * @param logFileDir
	 * @param delFileNames
	 * @param basePath
	 */
	public static void deleteFiles( File logFileDir,List<String> delFileNames,String basePath) {
		if(CollectionUtils.isNotEmpty(delFileNames)) {
			for(String fileName:delFileNames) {
				//删除文件
				File fileDebug = new File(basePath+"debug.log."+fileName);
				if(fileDebug.exists()) {
					LogUtil.info("删除日志文件：{}","debug.log."+fileName);
					fileDebug.delete();
				}
				File fileerror = new File(basePath+"error.log."+fileName);
				if(fileerror.exists()) {
					LogUtil.info("删除日志文件：{}", "error.log."+fileName);
					fileerror.delete();
				}
				File fileinfo = new File(basePath+"info.log."+fileName);
				if(fileinfo.exists()) {
					LogUtil.info("删除日志文件：{}", "info.log."+fileName);
					fileinfo.delete();
				}
				File filewarn = new File(basePath+"warn.log."+fileName);
				if(filewarn.exists()) {
					LogUtil.info("删除日志文件：{}", "warn.log."+fileName);
					filewarn.delete();
				}
			}
		}
	}
  public static void main(String[] args) throws ParseException, IOException {
	  File directory = new File("");// 参数为空
      String courseFile = directory.getCanonicalPath();
      System.out.println(courseFile);
	  
  }
}
